.TITLE LRDRV .IDENT /06/ ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 05 ; ; DAVID R. CROWE ; ; PREVIOUSLY MODIFIED BY: ; ; DAVID H. CHAN ; HELEN GORDON ; PATRICIA C. LEE ; ; MODIFIED BY: ; ; R. E. CALDWELL 21-AUG-79 ; ; RC011 -- USE CORRECT FORM OF GTPKT$. ; ; ; MODIFIED FOR RSX-11M-PLUS V4.2 BY: ; ; A. V. HUDED 06-SEP-88 06 ; ; AVH0004 --- MODIFIED TO SAVE THE LENGTH OF RECEPTION ; IN SECOND WORD OF I/O STATUS BLOCK ; ; PARALLEL COMMUNICATIONS LINK (PCL) RECEIVER DRIVER FOR RSX-11M-PLUS. ; ; MACRO LIBRARY CALLS. ; .MCALL PKTDF$,TCBDF$,UCBDF$ PKTDF$ ;DEFINE I/O PACKET OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS. UCBDF$ ;DEFINE UCB OFFSETS ;+ ; THIS DRIVER IS IN ONE OF A NUMBER OF SOFTWARE STATES DURING ITS ; OPERATION. ITS CURRENT STATE IS DEFINED IN THE LOW ORDER BYTE ; OF U.CW2 IN THE UCB. HANDLER STATES ARE DEFINED BELOW. ; ; INDEX MEANING ; 0 NO TASK CONNECTED. ; 2 TASK CONNECTED BUT NOT TRIGGERED. ; 4 TASK TRIGGERED & AWAITING ATF OR RTF. ; 6 TASK CONNECTED & TIMED OUT AWAITING ATF OR RTF. ; ; ... BUSY STATES ... ; THE CONTROLLER IS CONSIDERED BUSY BY RSX-11M WHILE THE ; HANDLER IS IN THESE STATES. THEREFORE ONLY THE INTERRUPT PROCESSOR ; NEED CONCERN ITSELF WITH THEM. BUSY STATES ARE AS FOLLOWS: ; ; -2 ATF IN PROGRESS. ; -4 TASK CONNECTED, NOT TRIGGERED, & HAS ATF PENDING. ; -6 RTF IN PROGRESS. ; ; LEGAL FUNCTIONS BY STATE. ; FUNCTION LEGAL STATES ; CRX 0 ; RTF 4, 6 ; ATF 2, 4, 6 ; DRX 2, 4, 6 ;- ;+ ; HANDLER UCB WORK AREA OFFSET DEFINITIONS. ;- U.TASK = U.CNT+2 ;TCB ADDR OF CONNECTED TASK [WORD] U.TEF = U.TASK+2 ;TRIGGER EVENT FLAG NO. [WORD] U.TRSB = U.TEF+2 ;REAL ADDRESS OF TRIGGER STATUS U.BUF1 = U.TRSB+4 ;ADDRESS OF RETURN BUFFER (2 WDS) U.AADA = U.BUF1+4 ;ATACHMENT DESCR. STORAGE ; BUFFER [2 WORDS] ;+ ; THE HARDWARE REGISTERS ARE DEFINED RELATIVE TO THE RCR, WHOSE ; ADDRESS IS FOUND IN THE S.CSR FIELD OF THE SCB AT RUN TIME. ;- RCR = 0 ;RECEIVER COMMAND REGISTER. RSR = 2 ;RECEIVER STATUS REGISTER. RDDB = 4 ;RECEIVER DESTINATION DATA BUFFER. RDBC = 6 ;RECEIVER DESTINATION BYTE COUNT. RDBA = 10 ;RECEIVER DESTINATION BUS ADDRESS. RDCRC = 12 ;RECEIVER DESTINATION CRC ;+ ; RECEIVER COMMAND REGISTER (RCR). ;- REJ = 100000 ;REJECT (R/W) RCNPR = 40000 ;RECEIVER NPR (R/W) RCVWD = 20000 ;RECEIVE WORD (R/W) IB04 = 10000 ;IDENTIFICATION BITS (RO) IB03 = 4000 ; " IB02 = 2000 ; " IB01 = 1000 ; " IB00 = 400 ; " LDSILO = 200 ;LOAD SILO (R/W) IE = 100 ;INTERRUPT ENABLE (R/W) A17 = 40 ;EXTENDED ADDRESS BITS (R/W) A16 = 20 ; " DTIRDY = 10 ;DATA INPUT READY (RO) INHADI = 4 ;INHIBIT ADDRESS INCREMENT (R/W) BDINIT = 2 ;BOARD INITIALIZE (WO) RCVDAT = 1 ;RECEIVE DATA (R/W) IB = IB04!IB03!IB02!IB01!IB00 ;UNION OF IDENTIFICATION BITS ;+ ; RECEIVER STATUS REGISTER (RSR). ;- ERR = 100000 ;ERROR (RO) NEXLOC = 40000 ;NONEXISTENT LOCATION (RO) MEMOFL = 20000 ;MEMORY OVERFLOW (R/W) TXMERR = 10000 ;TRANSMISSION ERROR (R/W) PAR = 4000 ;PARITY (R/W) TIMOUT = 2000 ;TIME OUT (R/W) BCOFL = 1000 ;BYTE COUNT OVERFLOW (R/W) DTORDY = 400 ;DATA OUTPUT READY (RO) SUCTXF = 200 ;SUCCESSFUL TRANSFER (R/W) BUSY = 100 ;BUSY (RO) RECOM = 40 ;REJECT COMPLETE (R/W) CHNOPN = 20 ;CHANNEL OPEN (RO) RSPB1 = 10 ;RESPONSE B1 (RO) RSPB0 = 4 ;RESPONSE B0 (RO) RSPA1 = 2 ;RESPONSE A1 (RO) RSPA0 = 1 ;RESPONSE A0 (RO) ;+ ; FUNCTION DISPATCH TABLE ;- FUNTBL: .IRP X, .WORD IO.'X, X .ENDM .WORD 0 ;TERMINATOR ;+ ; DEVICE DISPATCH TABLE ;- DDT$ LR,L$$R11,,CHK ;GENERATE DISPATCH TABLE ;+ ; LRCHK - PCL RECEIVER DRIVER PARAMETER CHECKING ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS RECEIVED FOR THE PARALLEL COMMUNICATIONS LINK RECEIVER. ; SOME PCL RECEIVER REQUESTS CONTAIN INFORMATION THAT MUST BE CHECKED ; IN THE CONTEXT OF THE ISSUING TASK; THEREFORE, THE I/O REQUEST IS NOT ; QUEUED BEFORE CALLING THE DRIVER. ; ; INPUTS: ; ; R1 = ADDRESS OF THE I/O PACKET ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED ; ; OUTPUTS: ; ; IF FUNCTION IS IO.CRX, ADDRESS CHECK IS PERFORMED FOR IOSB(8 BYTES) ; ; IF THE QIO FUNCTION IS IO.ATF THEN THE RETURN BUFFER ADDRESS IS ; CHECKED TO DETERMINE WHETHER IT LIES WITHIN THE ISSUING ; TASK'S ADDRESS SPACE. IF IT DOES THEN THE RETURN BUFFER ADDRESS IS ; RELOCATED AND STORED IN THE I/O PACKET. IF IT IS NOT A VALID ; ADDRESS THEN AN ILLEGAL BUFFER STATUS IS RETURNED AS THE FINAL ; I/O STATUS OF THE REQUEST. ; ; FOR ALL FUNCTION CODES, THE I/O PACKET IS INSERTED IN THE ; CONTROLLER QUEUE AND THE DEVICE INITIATOR IS ENTERED TO START ; THE CONTROLLER. ;- LRCHK: CMP #IO.CRX,I.FCN(R1) ;IS FUNCTION 'CRX'? BNE 5$ ;IF NE NO MOV R1,R3 ;SAVE IO PACKET ADDRESS MOV I.PRM+2(R3),R0 ;GET VIRTUAL ADDRESS OF BUFFER MOV #4.,R1 ;GET LENGTH 4 BYTES CALL $ACHKB ;CHECK THE ADDRESS BCS 10$ ;IF CS BAD MOV W.BATT(R2),R2 ;GET ATT. DESC. ADD. INCB A.IOC(R2) ;INCREMENT I/O COUNT MOV R2,I.PRM+6(R3) ;SAVE ATT. DESC. ADDR CALL $RELOC ;RELOCATE THE BUFFER MOV R1,I.PRM+2(R3) ;STORE BIAS MOV R2,I.PRM+4(R3) ;STORE ADDRESS MOV R3,R1 ;RESTORE IO PACKET ADDRESS BR 20$ ;CONTINUE 5$: CMP #IO.ATF,I.FCN(R1) ;IS FUNCTION CODE = 'ATF'? BNE 20$ ;IF NE NO ; ; 'ATF' FUNCTION - SET UP REGISTERS FOR ADDRESS CHECK AND RELOCATION ; ; R0 = ADDRESS TO CHECK AND RELOCATE ; R3 = ADDRESS OF THE I/O PACKET ; MOV R1,R3 ;SAVE ADDRESS OF THE I/O PACKET MOV I.PRM+6(R3),R0 ;GET VIRTUAL ADDRESS OF RETURN BUFFER ; ; VALIDATE THE RETURN BUFFER ADDRESS FOR THIS TASK ; MOV #12.,R1 ;SET LENGTH OF RETURN BUFFER TO 6 WORDS CALL $ACHCK ;CHECK THE ADDRESS BCC 15$ ;IF CC OK ; ; INVALID RETURN BUFFER ADDRESS - SET ILLEGAL BUFFER STATUS AND FINISH ; 10$: MOV #IE.SPC&377,R0 ;SET ILLEGAL BUFFER STATUS CALLR $IOFIN ;FINISH I/O OPERATION ; ; RELOCATE THE RETURN BUFFER ADDRESS ; 15$: MOV W.BATT(R2),R2 ;GET ATT. DESC. ADDR. INCB A.IOC(R2) ;INCREMENT I/O COUNT MOV R2,I.AADA+2(R3) ;SAVE PTR FOR $IODONE CALL $RELOC ;RELOCATE ADDRESS MOV R1,I.PRM+6(R3) ;RELOCATION BIAS ==> I/O PACKET MOV R2,I.PRM+10(R3) ;16-BIT ADDRESS ==> I/O PACKET MOV R3,R1 ;RESTORE R1 TO I/O PACKET ; ; INSERT THE I/O PACKET IN THE QUEUE ; 20$: MOV R4,R0 ;R0 = I/O QUEUE LISTHEAD CALL $QINSP ;GO INSERT PACKET IN QUEUE ; ; NOW GET THE I/O PACKET TO PROCESS. ; LRINI: GTPKT$ LR,L$$R11,,,T ;GET I/O PACKET MACRO ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1 = ADDRESS OF THE I/O PACKET. ; R2 = PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3 = CONTROLLER INDEX. ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK. ; R5 = ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; I/O REQUEST PACKET FORMAT: ; ; WD.00 = I/O QUEUE THREAD WORD ; WD.01 = REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD.02 = TCB ADDRESS OF REQUESTER TASK. ; WD.03 = POINTER TO 2ND LUN WORD IN REQUESTER TASK HEADER. ; WD.04 = CONTENTS OF 1ST LUN WORD IN REQUESTER TASK HEADER (UCB). ; WD.05 = I/O FUNCTION CODE. ; WD.06 = VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD.07 = RELOCATION BIAS OF I/O STATUS BLOCK. ; WD.10 = I/O STATUS BLOCK ADDRESS DISPLACEMENT + 140000. ; WD.11 = VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD.12 = FIRST PARAMETER OR RELOCATION BIAS OF DATA BUFFER ; WD.13 = SECOND PARAMETER OR 16-BIT ADDRESS OF DATA BUFFER ; WD.14 = THIRD PARAMETER OR LENGTH OF DATA BUFFER ; WD.15 = FOURTH PARAMETER OR RELOCATION BIAS OF RETURN BUFFER ; WD.16 = FIFTH PARAMETER OR 16-BIT ADDRESS OF RETURN BUFFER ; MOV I.TCB(R1),R0 ;GET TCB ADDRESS OF REQUESTOR BITB #T2.ABO,T.ST2(R0) ;IS TASK BEING ABORTED? BEQ 10$ ;IF EQ NO CALLR IEVER ;YES, IT'S FATAL 10$: MOV #FUNTBL,R0 ;GET ADDRESS OF FUNCTION TABLE 20$: CMP (R0),I.FCN(R1) ;FUNCTION CODES MATCH? BEQ 30$ ;IF EQ YES CMP (R0)+,(R0)+ ;MOVE TO NEXT ENTRY TST (R0) ;END OF TABLE? BNE 20$ ;IF NE NO CALLR IEIFC ;YES, ILLEGAL FUNCTION 30$: JMP @2(R0) ;GO TO FUNCTION PROCESSOR ;+ ; PROCESS 'CRX' FUNCTION ;- CRX: CMP I.PRM(R1),#96. ;IF TRIGGER EVENT FLAG > 64, BHI 20$ ;IF HI BAD TSTB U.CW2(R5) ;IS A TASK ALREADY CONNECTED ? BNE 10$ ;IF NE YES MOV I.PRM(R1),U.TEF(R5) ;SAVE TRIGGER EVENT FLAG NO. MOV I.PRM+2(R1),U.TRSB(R5) ;SAVE THE ADDRESS OF THE TRIGGER MOV I.PRM+4(R1),U.TRSB+2(R5) ;STATUS BUFFER MOV I.TCB(R1),U.TASK(R5) ;SAVE TCB ADDRESS MOV I.PRM+6(R1),U.AADA(R5) ;SAVE ATT. DESC. ADDR. CALL PRCRX ;CONNECT TASK FOR RECEPTION CALLR ISSUC ;INDICATE SUCCESS AND EXIT 10$: CALLR IEDAA ;SOMEONE ALREADY CONNECTED 20$: CALLR IEBAD ;BAD PARAMETER SPECIFIED ;+ ; **-PRCRX-PERFORM ACTUAL CONNECT FOR RECEPTION ; ; THIS ROUTINE IS CALLED TO CONNECT THE RECEIVER FOR RECEPTION. ; IT ACTIVATES THE HARDWARE TO RECEIVE A WORD, WHICH WILL BE ; TREATED AS A FLAGS WORD. IT SETS THE SOFTWARE STATE OF THE HANDLER ; TO 2. THE ROUTINE SHOULD BE CALLED WHENEVER THE HANDLER WISHES ; TO RECEIVE A FLAGS WORD. ; ; INPUTS: ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK (SCB) ; R5 = ADDRESS OF THE UNIT CONTROL BLOCK (UCB) ; ; OUTPUTS: ; THE RECEIVER IS INITIALIZED (BDINIT) & RCVWD IS SET. ; THE HANDLER IS SET TO SOFTWARE STATE 2. ; R0 IS SET POINTING TO THE RCR. ;- PRCRX: MOV U.BUF(R5),-(SP) ;SAVE BUFFER MOV U.BUF+2(R5),-(SP) ;ADDRESS MOV U.CNT(R5),-(SP) ;& COUNT. MOV U.TRSB(R5),U.BUF(R5) ;MOVE TRIGGER STATUS MOV U.TRSB+2(R5),U.BUF+2(R5) ;BUFFER ADDR TO U.BUF. MOV #4,U.CNT(R5) ;LOAD BYTE COUNT. CLR -(SP) ;SET STATUS BYTE TO ZERO. CALL $PTBYT ; " MOV (SP)+,U.CNT(R5) ;RESTORE BUFFER MOV (SP)+,U.BUF+2(R5) ;ADDRESS MOV (SP)+,U.BUF(R5) ;& COUNT. MOV S.CSR(R4),R0 ;GET ADDRESS OF RCR BIS #BDINIT,(R0) ;INITIALIZE RECEIVER. BIS #RCVWD!IE,(R0) ;PREPARE TO RECEIVE A FLAG WD. MOVB #2,U.CW2(R5) ;SET HANDLER STATE TO 2. RETURN ; ;+ ; PROCESS 'RTF' FUNCTION ;- RTF: CMP I.TCB(R1),U.TASK(R5) ;RTF FROM CONNECTED TASK? BEQ 10$ ;IF EQ YES CALLR IEDNA ;NO, DEVICE NOT AVAILABLE 10$: MOVB U.CW2(R5),R0 ;GET HANDLER STATE. BIC #^C6,R0 ;MASK OUT UNWANTED BITS JMP @RTFJMP(R0) ;PROCESS FUNCTION ACCORDING STATE RTFJMP: .WORD IEDNA ;STATE 0 .WORD IENTR ;STATE 2 .WORD RTFS4 ;STATE 4 .WORD RTFS6 ;STATE 6 RTFS4: MOV S.CSR(R4),R0 ;GET ADDRESS OF RCR BIS #REJ!IE,(R0) ;SET REJECT & INT ENABLE. MOVB #-6,U.CW2(R5) ;SET HANDLER STATE TO -6. MOVB S.ITM(R4),S.CTM(R4) ;SET TIME OUT RETURN ; RTFS6: MOVB #2,U.CW2(R5) ;SET HANDLER STATE TO 2. CALLR IEDNR ;FORCE DRIVE NOT READY ;+ ; PROCESS 'ATF' FUNCTION ;- ATF: ;REF LABEL .IF DF M$$EXT CALL $STMAP ;SET UP UNIBUS MAP ADDRESS .ENDC MOV I.PRM+6(R1),U.BUF1(R5) ;RELOCATION BIAS ==> UCB MOV I.PRM+10(R1),U.BUF1+2(R5) ;16-BIT ADDRESS ==> UCB CMP I.TCB(R1),U.TASK(R5) ;ATF FROM CONNECTED TASK? BEQ 10$ ;IF EQ YES CALLR IEDNA ;NO, DEVICE NOT AVAILABLE 10$: MOVB U.CW2(R5),R0 ;GET HANDLER STATE. BIC #^C6,R0 ;CLEAR UNWANTED BITS JMP @ATFJMP(R0) ;PROCESS FUNCTION ACCORDING TO STATE ATFJMP: .WORD IEDNA ;STATE 0 .WORD ATFS2 ;STATE 2 .WORD PRATF ;STATE 4 .WORD RTFS6 ;STATE 6 ATFS2: MOVB #-4,U.CW2(R5) CLRB S.CTM(R4) ;NO TIME OUT ON THIS RETURN ; ;+ ; **-PRATF-PERFORM ACCEPTANCE OF TRANSFER ; ; THIS ROUTINE IS CALLED TO INITIATE THE RECEPTION OF THE MESSAGE ; WHICH HAS JUST BEEN ACCEPTED. THE STATE OF THE HANDLER IS SET ; TO -2, WHICH INDICATES THAT THE HANDLER IS BUSY PERFORMING ; THE ACCEPT TRANSFER FUNCTION. ; ; INPUTS: ; R4 = ADDRESS OF THE STATUS CONTROL BLOCK (SCB) ; R5 = ADDRESS OF THE UNIT CONTROL BLOCK (UCB) ; ; OUTPUTS: ; THE RDBC & RDBA ARE SET UP, & AN NPR RCVDAT FUNCTION IS INITIATED. ; THE HANDLER IS SET TO STATE -2. ; R0 IS SET POINTING TO THE RCR. ; R2 IS DESTROYED. ;- PRATF: ;REF LABEL .IF DF M$$EXT CALL $MPUBM ;MAP UNIBUS TO MEMORY MOV S.PKT(R4),R1 ;RETREIVE I/O PACKET ADDRESS .ENDC MOV S.CSR(R4),R0 ;GET ADDRESS OF RCR MOV U.BUF+2(R5),RDBA(R0) ;LOAD BUFFER ADDRESS REGISTER. MOV U.CNT(R5),R2 ;GET BYTE COUNT. NEG R2 ;NEGATE IT & LOAD MOV R2,RDBC(R0) ;BYTE COUNT REGISTER. MOVB #-2,U.CW2(R5) ;SET HANDLER STATE TO -2. BIS #RCNPR!RCVDAT!IE,U.BUF(R5) ;SET RCNPR, RCVDAT, IE, & BIS U.BUF(R5),(R0) ;EXTENDED ADDR BITS IN RCR. MOVB S.ITM(R4),S.CTM(R4) ;SET TIME OUT RETURN ; ;+ ; PROCESS 'DRX' FUNCTION ;- DRX: TSTB U.CW2(R5) ;IS ANY TASK CONNECTED ? BEQ 10$ ;IF EQ NO MOV I.TCB(R1),R1 ;YES, GET TCB ADDRESS. CMP R1,U.TASK(R5) ;IS THIS TASK CONNECTED ? BNE 10$ ;IF NE NO CALL PRDRX ;DO THE DISCONNECT CALLR ISSUC ;EXIT WITH SUCCESS 10$: CALLR IEDNA ;DEVICE NOT AVAILABLE ;+ ; **-PRDRX-PERFORM ACTUAL DISCONNECT FROM RECEPTION ; ; THIS ROUTINE DISCONNECTS THE RECEIVING TASK FROM RECEPTION. ; ; INPUTS: ; R1 = ADDRESS OF TCB FOR TASK. ; R4 = SCB ADDRESS. ; R5 = UCB ADDRESS. ; ; OUTPUTS: ; THE I/O REQUEST COUNT FOR THE TASK IS DECREMENTED. ; THE RECEIVER IS INITIALIZED (BDINIT). ; THE HANDLER STATE IS SET TO 0. ; R0 IS SET POINTING TO THE RCR. ;- PRDRX: MOV U.AADA(R5),R0 ;GET ATTACHMENT DESCRIPTOR ADDRESS DECB A.IOC(R0) ;DECREMENT I/O COUNT MOV S.CSR(R4),R0 ;GET ADDRESS OF RCR BIS #BDINIT,(R0) ;INITIALIZE RECEIVER BOARD. CLR U.AADA(R5) ;CLEAR ATTACHED REGION DESC. CLR U.TASK(R5) ;CLEAR TCB ADDRESS OF CONNECTED TASK CLR U.TEF(R5) ;CLEAR EVENT FLAG ALSO CLRB U.CW2(R5) ;SET HANDLER STATE TO 0. RETURN ; ;+ ; **-$LRINT-PCL RECEIVER INTERRUPT PROCESSOR ; ; INTERRUPTS ARE PROCESSED DEPENDING UPON THE HANDLER STATE. ;- $LRINT:: INTSV$ LR,PR5,L$$R11 ;;;GENERATE INTERRUPT SAVE STUFF MOV U.SCB(R5),R4 ;;;GET SCB ADDRESS. MOV S.CSR(R4),R4 ;;;GET RCR ADDRESS. BIC #IE,(R4) ;;;DISABLE PCL INTERRUPTS. CALL $FORK ;;;CREATE A FORK PROCESS. MOV R4,R0 ;COPY RCR ADDRESS MOV U.SCB(R5),R4 ;GET SCB ADDRESS. MOVB U.CW2(R5),R2 ;GET HANDLER STATE. JMP @INTJMP(R2) ;PROCESS INTERRUPT ACCORDING TO STATE .WORD INTM6 ;STATE -6 .WORD INTM4 ;STATE -4 .WORD INTM2 ;STATE -2 INTJMP: .WORD INTP0 ;STATE 0 .WORD INTP2 ;STATE 2 .WORD INTP4 ;STATE 4 .WORD INTP6 ;STATE 6 ; ; THE VARIOUS INTERRUPT STATE PROCESSORS WHICH ARE JUMPED TO ; THROUGH THE INTJMP TABLE ARE ENTERED WITH REGISTERS SET AS FOLLOWS: ; R0 = RCR ADDRESS ; R2 = HANDLER STATE ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; INTM6: BIT #ERR!SUCTXF,RSR(R0) ;ERROR OF SUCTXF? BNE 10$ ;IF NE YES BIT #RECOM,RSR(R0) ;IS RECOM SET? BEQ 10$ ;IF EQ NO CALL PRCRX ;RECONNECT FOR RECEPTION CALLR ISSUC ;EXIT WITH SUCCESS 10$: CALLR IEFHE ;FATAL HARDWARE ERROR INTM4: INTP2: INTP6: TST RSR(R0) ;ANY ERRORS? BMI 10$ ;IF MI YES BIT #RECOM,RSR(R0) ;REJECT COMPLETION? BNE 20$ ;IF NE YES BIT #DTORDY,RSR(R0) ;DATA OUTPUT READY? BNE 40$ ;IF NE YES CALLR PRCRX ;RECONNECT FOR RECEPTION AND EXIT 10$: BIT #PAR,(R0) ;IS IT PARITY ERROR ? BNE 20$ ;IF NE YES NOP 20$: CALL PRCRX ;RECONNECT FOR RECEPTION MOVB R2,U.CW2(R5) ;MOVE STATE TO AS BEFORE. RETURN ; 40$: TST R2 ;IS HANDLER STATE -4 ? BGE 60$ ;IF GE NO, GIVE FLAGS WORD TO TASK TST RDDB(R0) ; CALLR PRATF ;ACCEPT TRANSFER 60$: MOV U.BUF(R5),-(SP) ;SAVE BUFFER ADDR & COUNT. MOV U.BUF+2(R5),-(SP) ; MOV U.CNT(R5),-(SP) ; MOV U.TRSB(R5),U.BUF(R5) ;LOAD TRIGGER STATUS BLOCK ADDRESS MOV U.TRSB+2(R5),U.BUF+2(R5) ; MOV #4,U.CNT(R5) ;LOAD A BIG ENOUGH COUNT. CMP R2,#2 ;IS THE STATUS=2? BEQ 70$ ;IF EQ YES MOV #&377,R2 ; STATE 6 ==> STATUS IE.DAO 70$: ASRB R2 ; MOV (R0),R3 ;GET CONTENTS OF RCR BIC #^C,R3 ;ISOLATE TRANSMITTER ID. BIS R3,R2 ;MERGE WITH STATUS. MOV R2,-(SP) ;GET FIRST STATUS WORD CALL $PTWRD ;PUT IN USERS BUFFER MOV RDDB(R0),-(SP) ;GET SECOND STATUS WORD CALL $PTWRD ;PUT IN USERS BUFFER MOV (SP)+,U.CNT(R5) ;RESTORE COUNT AND BUFFER ADDRESS MOV (SP)+,U.BUF+2(R5) ; MOV (SP)+,U.BUF(R5) ; MOVB #4,U.CW2(R5) ;SET STATE TO 4. BIS #IE,(R0) ;REENABLE INTERRUPTS. MOV U.TEF(R5),R0 ;GET TRIGGER EVENT FLAG NO. MOV U.TASK(R5),R5 ;GET TCB ADDR FOR CONNECTED TASK. BEQ 90$ ;IF EQ NONE CALL $CEFI ;CONV EVENT FLAG TO MASK & ADDR. BCS 90$ ;IF CS NO FLAG SPECIFIED BIS R0,(R1) ;SET FLAG 90$: CALLR $DRDSE ;DECLARE SIGNIFICANT EVENT. INTM2: TST RSR(R0) ;ANY ERRORS? BMI M2ERR ;IF MI YES TSTB RSR(R0) ;SUCCESSFUL TRANSFER? BPL M2PAR ;IF PL NO M2SUC: MOV (R0),R2 ;GET CONTENTS OF RCR. BIC #^C,R2 ;RETRIEVE TRANSMITTER ID. BIS #IS.SUC,R2 ;MERGE IN RETURN STATUS BIT #RECOM,RSR(R0) ;REJECT COMPLETE? BEQ 10$ ;IF EQ NO INC R2 ; +2 FOR TRUNCATED RECEPTION 10$: MOV RDBC(R0),R1 ;COMPUTE LENGTH OF RECEPTION. ADD U.CNT(R5),R1 ; MOV U.BUF(R5),-(SP) ;SAVE U.BUF MOV U.BUF+2(R5),-(SP) ;SAVE U.BUF+2 MOV U.CNT(R5),-(SP) ;SAVE U.CNT MOV U.BUF1(R5),U.BUF(R5) ;RELOCATION BIAS ==> UCB BEQ 20$ ;IF EQ ZERO MOV U.BUF1+2(R5),U.BUF+2(R5) ;16-BIT ADDRESS ==> UCB BR 30$ ;GO MOVE THE REGISTERS ; ; RELOCATION BIAS = 0 CHECK FOR NON-ZERO 16-BIT ADDRESS ; 20$: MOV U.BUF1+2(R5),U.BUF+2(R5) ;16-BIT ADDRESS ==> UCB BEQ 40$ ;IF EQ NO RETURN ADDRESS ; ; REGISTERS REQUESTED - RETURN THEM ; 30$: MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER MOV (R0)+,-(SP) ;GET CONTENTS OF REGISTER CALL $PTWRD ;PUT IT IN USERS BUFFER ; ; CONTINUE PROCESSING ; 40$: MOV (SP)+,U.CNT(R5) ;RESTORE U.CNT MOV (SP)+,U.BUF+2(R5) ;RESTORE U.BUF+2 MOV (SP)+,U.BUF(R5) ;RESTORE U.BUF CALL PRCRX ;RECONNECT FOR RECEPTION MOV R2,R0 ;COPY STATUS CODE CALL $IODON ;FINISH I/O JMP LRINI ;TRY FOR MORE WORK M2ERR: MOV RSR(R0),R1 ;GET CONTENTS OF RSR BIT #BCOFL,R1 ;CHECK FOR BYTE COUNT BNE 10$ ;IF NE OVERFLOW BIT #PAR!TXMERR,R1 ;PARITY OR TRANSMISSION ERROR? BNE M2PAR ;IF NE YES BIT #TIMOUT,R1 ;CHECK FOR TIME OUT. BNE M2TIME ;IF NE YES BIT #MEMOFL!NEXLOC,R1 ;NEM OR OVERFLOW? BNE M2OFL ;IF NE YES CALLR IEBBE ;INDICATE TRANSMISSION ERROR ; ; BYTE COUNT OVERFLOW ; 10$: BIC #BCOFL,RSR(R0) ;CLEAR ERROR CONDITION. BIS #REJ!IE,(R0) ;TRUNCATE MESSAGE RETURN ; ; ; PARITY OR TRANSMISSION ERROR ; M2PAR: CALL PRCRX ;RECONNECT FOR RECEPTION BR IEBBE ;FLAG IE.BBE ; ; RECEIVER TIMEOUT ; M2TIME: CALL PRCRX ;RECONNECT FOR RECEPTION BR IEDNR ;FLAG DEVICE NOT READY ; ; NONEXISTENT LOCATION OR MEMORY OVERFLOW. ; M2OFL: CALL PRCRX ;RECONNECT FOR RECEPTION BR IESPC ;INDICATE NONEXISTENT LOCATION INTP0: BIS #BDINIT,(R0) ;INITIALIZE BOARD. RETURN ; INTP4: CALL PRCRX ;RECONNECT FOR RECEPTION MOVB #6,U.CW2(R5) ;SET HANDLER STATE TO 6. RETURN ; ;+ ; **-LRCAN-CANCEL I/O SERVICE ROUTINE ; ; THIS ENTRY POINT IS ENTERED WHEN AN IO.KIL FUNCTION IS ; ISSUED REGARDLESS OF WHETHER THE DEVICE IS BUSY OR NOT. ; ; INPUTS: ; R0 = ADDRESS OF ACTIVE I/O PACKET (IF ANY) ; R1 = ADDRESS OF TCB OF CURRENT TASK ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; 1. IF TASK TERMINATION IS IN PROGRESS, THEN BOARD IS ; INITIALIZED & TASK (IF ANY) IS DISCONNECTED. ; 2. OTHERWISE, IF REQUEST IS OUTSTANDING, THEN TASK IS ; RECONNECTED FOR RECEPTION. ; 3. REGARDLESS OF RUN DOWN STATUS, IF REQUEST IS OUTSTANDING, ; THEN COMPLETION IS INDICATED WITH STS=IE.ABO. ;- LRCAN: CMP R1,U.TASK(R5) ;;;REQUEST FOR CONNECTED TASK? BNE 10$ ;;;IF NE NO MOV S.CSR(R4),R3 ;;;GET RCR ADDRESS. BIC #IE,(R3) ;;;DISABLE INTERRUPTS. MTPS #0 ;;;LOWER PRIORITY BITB #T2.HLT,T.ST2(R1) ;TASK BEING TERMINATED? BEQ 20$ ;IF EQ NO MOVB U.CW2(R5),R2 ;YES, RETRIEVE HANDLER STATE. CALL PRDRX ;DISCONNECT TASK TSTB R2 ;IS UNIT BUSY? BLT 30$ ;IF LT YES 10$: RETURN ; 20$: TSTB U.CW2(R5) ;IS UNIT BUSY? BGE 10$ ;IF GE YES CALL PRCRX ;ABORT OPERATION AND RECONNECT 30$: BR IEABO ; ;+ ; POWERFAIL AND TIMEOUT ;- LROUT: TSTB U.CW2(R5) ;IS TASK CONNECTED? BEQ 10$ ;IF EQ YES CALL PRCRX ;RECONNECT FOR RECEPTION 10$: BITB #US.BSY,U.STS(R5) ;IS THE UNIT BUSY? BEQ LRPWF ;IF EQ NO BR IEDNR ;YES, ABORT OUTSTANDING REQUEST LRPWF: RETURN ; ;+ ; PROCESS ERROR CONDITIONS AND CALL I/O DONE. ;- IEABO: MOV #IE.ABO&377,R0 ;ABORT TASK BR IODON ; IEBAD: MOV #IE.BAD&377,R0 ;BAD PARAMETERS BR IODON ; IEDAA: MOV #IE.DAA&377,R0 ;DEVICE ALREADY CONNECTED BR IODON ; IEBBE: MOV #IE.BBE&377,R0 ;BAD TRANSMISSION ERROR BR IODON ; IEDNA: MOV #IE.DNA&377,R0 ;DEVICE NOT AVAILABLE BR IODON ; IEDNR: MOV #IE.DNR&377,R0 ;DEVICE NOT READY BR IODON ; IEFHE: MOV #IE.FHE&377,R0 ;FATAL HARDWARE ERROR BR IODON ; IEIFC: MOV #IE.IFC&377,R0 ;INVALID FUNCTION CODE BR IODON ; IENTR: MOV #IE.NTR&377,R0 ;TASK NOT TRIGGERED BR IODON ; IESPC: MOV #IE.SPC&377,R0 ;ILLEGAL BUFFER BR IODON ; IEVER: MOV #IE.VER&377,R0 ;PARITY OR HARD DEVICE ERROR BR IODON ; ISSUC: MOV #IS.SUC&377,R0 ;SUCCESSFUL OPERATION IODON: CALL $IOALT ;PROCESS I/O DONE JMP LRINI ;AND TRY FOR MORE .END